home *** CD-ROM | disk | FTP | other *** search
- /***
- *disklib.c - disk editor
- *
- *Copyright (c) 1991-1994, Gregg Jennings. All wrongs reserved.
- * P O Box 200, Falmouth, MA 02541-0200
- *
- *Purpose:
- * MS(tm)-DOS Disk EDitor main library functions.
- *
- *Notice:
- * This progam may be freely used and distributed. Any distrubution
- * with modifications must retain the above copyright statement and
- * modifications noted.
- * No pulp-publication, in whole or in part, permitted without
- * permission (magazines or books).
- *******************************************************************************/
-
- /*
- Versions
-
- 2.1 04-Jan-1994 added Translate if !Files for startup
- added 'dir_cluster'
- help()
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <malloc.h>
- #include <errno.h>
-
- #include "disked.h"
- #include "diskio.h"
- #include "mylib.h"
- #include "files.h"
- #include "keys.h"
- #include "error.h"
- #include "dpb.h"
- #include "dirent.h"
-
- /*********** EXTERNAL DATA ***********/
-
- extern unsigned int byte_cnt; /* buffer byte count: append fileio find */
- extern unsigned int max_bytes; /* maximum buffer size: append fileio dparams */
- extern unsigned char *data_buf; /* data buffer: append fileio find */
- extern int diskio_error;
- extern unsigned int dir_cluster;
-
- /* display keywords */
-
- void dkey(register struct Keys *str)
- {
- register int i;
-
- print("\nON: ");
- for (i=1;i<str->opt;i++)
- if ((str+i)->opt)
- {
- print((str+i)->s);
- send(' ');
- }
- print("\nOFF: ");
- for (i=1;i<str->opt;i++)
- if (!(str+i)->opt)
- {
- print((str+i)->s);
- send(' ');
- }
- }
-
- /* display keyword */
-
- void psw(char c, register struct Keys *str)
- {
- register int i;
-
- for (i=1;i<str->opt;i++)
- {
- if ((str+i)->s[0]==c)
- {
- print((str+i)->s);
- print(((str+i)->opt)?":ON ":":OFF ");
- break;
- }
- }
- }
-
- /* set keyword */
-
- void ckey(register char *s, register struct Keys *str)
- {
- register int i;
-
- do
- {
- for (i=1;i<str->opt;i++)
- {
- if ((str+i)->s[0]==*s)
- {
- (str+i)->opt++;
- if ((str+i)->opt>1)
- (str+i)->opt-=2;
- break;
- }
- }
- } while (*++s);
- }
-
- void commands(void)
- {
- print(" Commands:\n\n");
- print(" Drive: Movement: File Buffer: \n");
- print(" 'ld' log disk d 'n' next sector 'a' append sector \n");
- print(" '^L' re-log drive 'b' back sector 'u' unappend sector \n");
- print(" 'fs' find string s 'h' next head 'A' append cluster \n");
- print(" BS displat stats 'N' next cluster 'U' unappend cluster\n");
- print(" 'B' back cluster '^An' append n bytes \n");
- print(" Sector Buffer: '^N' next track '^Un' unappend n bytes \n");
- print(" 'c' change from n '^B' back track 'gn' get n sectors \n");
- print(" '^C' change dir 'sn,n,n' set position '^Gn' get n sectors & move \n");
- print(" 'k' kill changes 'Sn' set to cluster n 'dn' display from n \n");
- print(" '>' store '^Sn' set to sector n 'vn' view from n \n");
- print(" '<' retrieve 'r' range 'e' empty \n");
- print(" 'w' write 'H' home '^E' empty no ask \n");
- print(" SPACE display top 'E' end 'ps' put to file s \n");
- print(" CR display rest F10s goto file s '^Ps' put no options\n");
- print(" 'tn' tag sector ^END end of file 'is' insert file s \n");
- print(" '1-9' goto tag ^HOME start of file '^Is' insert no options\n");
- print(" ^RIGHT next file cluster 'I' insert current file\n");
- print(" 'q' quit ^LEFT back file cluster 'Cn' change from n \n");
- print(" '?' more help 'Fs' find string s \n");
- }
-
- void ext_commands(void)
- {
- print(" Extra Commands:\n\n");
- print(" 'z' set params 'Z' display params ',' toggle input radix\n");
- print(" '^X' restore state '^Z' save state '!' shell to DOS\n");
- print(" 'x' view ini file 'X' view sav file '^Q' quit no ask \n");
- print(" 'm' map file 'M' map free space 'Pn,n,s' put sectors to s\n");
- print(" F1 directory F2 list files F3 number of files\n");
- print(" F4s change directory F5 re-read sector F6 append w/strip\n");
- print(" F7 append w/convert F8 append w/mask F9 append w/options\n");
- print(" SF1 display partial SF2 display full SF3 display ascii\n");
- print(" SF4 display directory SF6 DOS help \n");
- print("SRIGHT next free clus. SLEFT back free clus. \n");
- }
-
- /* set to track, sector, head
-
- Passed pointer to string, number of values, and struct of type
- Msg which holds the messages to display for each value and
- the number of digits for each value.
-
- Modification of get() to return immediately on an 'f' or 'b'.
-
- Uses Display, Radix.
-
- Returns a string containing the values seperated by commas
- to be converted by sscanf().
- */
-
- int set(struct Msg *str,int *t, int *s, int *h)
- {
- register int c,i,n;
- long l;
- char ts[7];
-
- for (i=n=0; n < 3; n++,i=0,str++)
- {
- if (Display)
- print(str->msg);
- while ((c=input())!='\r' && c!=' ' && c!=',')
- {
- if (n==0 && i==0 && (c=='f' || c=='b'))
- {
- conout(c);
- return(c);
- }
- if (c=='\b'&& i!=0) /* backspace, delete number */
- {
- conout(c); /* in buffer */
- conout(' '); /* and on screen */
- conout(c);
- --i; /* move pointer back */
- }
- else if (c==0x1b || c==3) /* ESC to abort */
- return(0);
- else if (Radix==16 && !isxdigit(c))
- continue;
- else if (Radix==10 && !isdigit(c))
- continue;
- else
- {
- conout(c);
- ts[i++]=(char)c; /* save and echo numbers */
- if (i==str->len)
- break;
- }
- }
- ts[i]='\0';
- if (i)
- {
- l=strtol(ts,NULL,Radix);
- if (n==0)
- *t=(int)l;
- else if (n==1)
- *s=(int)l;
- else
- *h=(int)l;
- }
- if (c=='\r')
- break;
- if (!Display && n < 2)
- conout(',');
- }
- return(1);
- }
-
- /* get a string for conversion to numbers
-
- Passed pointer to string, number of values, and struct of type
- Msg which holds the messages to display for each value and
- the number of digits for each value.
-
- Uses Display, Radix.
-
- Returns a string containing the values seperated by commas
- to be converted by sscanf().
-
- */
- int get(struct Msg *str,int *one, int *two)
- {
- register int t,v;
- char temp[7];
-
- for (t=0; t < 2; t++,str++)
- {
- if (Display)
- print(str->msg);
- if (getstr(temp,str->len,(Radix==16)?_HEX:_DIGIT) > 0)
- {
- v=atoi(temp);
- if (t==0)
- *one = v;
- else
- *two = v;
- }
- else
- return(0);
- if (!Display && t < 1)
- conout(',');
- }
- return(1);
- }
-
- /* get - long version */
-
- int getl(struct Msg *str,long *one, int *two)
- {
- register int t;
- int i;
- char temp[7];
- long l;
-
- for (t=0; t < 2; t++,str++)
- {
- if (Display)
- print(str->msg);
- if ((i=getstr(temp,str->len,(Radix==16)?_HEX:_DIGIT)) > 0)
- {
- l=strtol(temp,NULL,Radix);
- if (t==0)
- *one = l;
- else
- *two = (int)l;
- }
- else if (!t && i == -3)
- putlong(*one);
- else
- return(0);
- if (!Display && t < 1)
- conout(',');
- }
- return(1);
- }
-
- /* displau sector header */
-
- void header(void)
- {
- register unsigned int i,j;
-
- if (Logical==0)
- {
- if (Radix==10)
- printf("\ntrack %u, sector %u(%lu), head %u",track,sector,log_sector,head);
- else
- printf("\ntrack %x, sector %x(%lx), head %x",track,sector,log_sector,head);
- }
- else
- {
- print("\nsector ");
- putlong(log_sector);
- }
- i=sectortocluster(log_sector);
- j=clustersector(log_sector)+1;
-
- if (log_sector>(dword)data_sector)
- {
- if (Radix==10)
- printf(", cluster %u:%u",i,j);
- else
- printf(", cluster %x:%x",i,j);
- }
- else
- { unsigned sector = (word)log_sector;
- if (sector < reserved_secs)
- {
- print(" BOOT");
- if (reserved_secs>1)
- printf(" %d:%d",sector+1,reserved_secs);
- }
- else if (sector >= reserved_secs && sector <= secs_fat)
- printf(" FAT 1 %d:%d %d-BIT",
- sector-reserved_secs+1,secs_fat,fat_size);
- else if (num_fats > 1 && sector > secs_fat
- && sector <= (secs_fat*num_fats))
- printf(" FAT 2 %d:%d %d-BIT",
- (sector-reserved_secs-secs_fat)+1,secs_fat,fat_size);
- else if (sector >= dir_sector && sector <= data_sector)
- printf(" ROOT %d:%d",(sector-dir_sector)+1,dir_sectors);
- }
- if (diskio_error)
- print(" <BAD>");
- if (Files>0 && n_files && log_sector>(dword)data_sector && i<num_clusters)
- {
- if (clusters[i]>0 && (unsigned)clusters[i]<=n_files)
- {
- send(' ');
- print(gfile(clusters[i]));
- if (files[clusters[i]].dir)
- print(" <DIR>");
- }
- }
- }
-
- void dparams(char *drivedir) /* display disk drive info */
- {
- print("\n\n\tSerial No:");print(Version);
- print("\t DOS Version: ");putbyte(_osmajor);conout('.');putbyte(_osminor);
-
- print("\n\tbuffer size: ");putuint(max_bytes);
- print("\t media: ");print(format);
-
- print("\n\tnumber of drives: ");putuint(max_drive);
- print("\t volume: ");print( (volume[0]=='\0') ? "? " : volume);
-
- print("\n\tcurrent drive: ");putch(disk+'@');putch(':');
- print("\t current dir: ");print(&drivedir[2]);
-
- if (Logical==0)
- {
- print("\n\tdrive size: ");putlong(drive_size);
- print("\t reserved sectors: ");putuint(reserved_secs);
-
- print("\n\tsector size: ");putuint(sec_size);
- print("\t sectors/fat: ");putuint(secs_fat);
-
- print("\n\ttracks: 0-");putuint(max_track);
- print("\t\t number fats: ");putuint(num_fats);
-
- print("\n\tsectors: 1-");putuint(max_sector);
- print("\t\t root directory: ");putuint(dir_sector);
-
- print("\n\theads: 0-");putuint(max_head-1);
- print("\t\t data sector: ");putuint(data_sector);
- }
- else
- {
- print("\n\tdrive size: ");putlong(drive_size);
- print("\t sectors: 0-");putuint(num_sectors-1);
-
- print("\n\tsector size: ");putuint(sec_size);
- print("\t clusters: 2-");putuint(num_clusters);
-
- print("\n\tcluster size: ");putuint(cluster_size);
- print("\t sectors/cluster: ");putuint(secs_cluster);
-
- print("\n\tsectors/fat: ");putuint(secs_fat);
- print("\t\t number fats: ");putuint(num_fats);
-
- print("\n\troot directory: ");putuint(dir_sector);
- print("\t data sector: ");putuint(data_sector);
- }
- }
-
- /*************************************************************************
- Display Functions
- ************************************************************************/
-
- /* display databuffer, displaying all non-printable
- characters enclosed in <>
-
- Another complicated, horrible looking function.
-
- */
-
- view(
- register unsigned char *buffer, /* array of data */
- unsigned int bfptr, /* index into array */
- unsigned int bufend, /* size of array */
- int pause,
- int base)
- {
- register int c;
- int length;
- int p,n,nn,np;
-
- p=n=nn=np=0;
- send('\n');
- if (pause)
- {
- length=21;
- pnlz(bfptr,(getlen(bfptr,base)),base);
- send(':');
- send('\n');
- }
- else
- {
- length=sec_size;
- send('\n');
- }
- do
- {
- c=(int)buffer[bfptr++];
- if (bfptr>bufend)
- {
- bfptr=0;
- break;
- }
- if (p>75)
- {
- p=0;
- ++n;
- ++nn;
- ++np;
- }
- if (!isprint(c) && !isspace(c))
- {
- if (Strip) /* do we strip? */
- continue;
- if (Mask) /* do we mask ? */
- c&=0x7f;
- else if (Convert) /* do we convert? */
- {
- printf("<%02x>",c);
- p+=4;
- continue;
- }
- }
- if (c==7 || c==255 || c==0 || c==8)
- continue;
- if (c=='\n')
- {
- n++;
- ++nn;
- p=0;
- }
- if (c!='\r')
- p+=send(c);
- } while (n<length);
-
- if (pause)
- {
- send('\n');
- pnlz(bfptr,(getlen(bfptr,base)),base);
- conout(':');
- }
- return(bfptr);
- }
-
- /* lame attempt to display BOOT parameters */
-
- void dumpboot(byte *buf)
- {
- struct BOOT b;
- int i;
-
- memcpy(&b,buf,sizeof(struct BOOT));
- send('\n');
- switch(b.jump[0])
- {
- case 0xeb:
- print("JMP SHORT ");
- puthex(b.jump[1]);
- break;
- case 0xe9:
- print("JMP ");
- puthex(b.jump[1]);conout(':');puthex(b.jump[2]);
- break;
- case 0xff:
- case 0xea:
- print("JMP other ");
- break;
- default:
- print("unknown");
- }
- send('\n');
- printf("OEM name:\t\t\t");
- for (i=0;i<8;i++)
- printf("%02X",b.name[i]);
- printf("\nbytes per sector: %04X\n",b.sec_size);
- printf("sectors per allocation unit: %02X\n",b.secs_cluster);
- printf("reserved sectors: %04X\n",b.reserved_secs);
- printf("number of FATs: %02X\n",b.num_fats);
- printf("number of root dir entries: %04X\n",b.dir_entries);
- printf("number of sectors in logical image: %04X\n",b.num_sectors);
- printf("media descriptor: %02X\n",b.media_desc);
- printf("number of FAT sectors: %04X\n",b.secs_fat);
- printf("sectors per track: %04X\n",b.secs_track);
- printf("number of heads: %04X\n",b.num_heads);
- printf("number of hidden sectors: %04X\n",b.hidden_sectors);
- printf("high order number of hidden sectors: %04X\n",b.large_sectors);
- printf("number of logical sectors: %08X\n",b.total_sectors);
-
- }
-
- /*
- Search for an ascii string ( converted by convert() ) on the disk,
- sector by sector, asking to continue if not found after MAXSECTORS.
-
- findstr holds the "converted" string, tmpfstr holds the original string
-
- ver 2.0 10-93 added case test
-
- returns: ERROR (-1) on error, stopped, or not found
- ABORT (-2) on user cancelled
- or the byte position of the string
- */
-
- char findstr[SEARCH+1]; /* string to search disk for */
- char tmpfstr[SEARCH+1]; /* plus a bunch extra */
- unsigned int findlen=0;
-
- int find(int val, int get, int kase)
- {
- int findval; /* return value */
- unsigned long ntimes;
- register int io;
- char str[SEARCH+1]; /* 4 times max string length */
-
- findval=-1;
- io=0;
- ntimes=0L;
- str[0]='\0';
- if (get)
- {
- if (getstr(str,SEARCH,_PUNCT)==ABORT) /* get string */
- return(ABORT); /* return on ESC or ^C */
- if (str[0]=='\0' && findlen==0) /* is no string to search for */
- return(ABORT); /* then return ABORT */
- if (str[0]) /* save the string in tempstr */
- {
- strcpy(findstr,str); /* to search for the same string */
- strcpy(tmpfstr,str); /* tmpfstr holds the un-converted */
- findlen=convert(findstr); /* convert if needed */
- }
- else
- print(tmpfstr);
- }
- else
- {
- strcpy(tmpfstr,findstr); /* tmpfstr holds the un-converted */
- findlen=convert(findstr); /* convert if needed */
- }
- conout(' ');
- if (val==0) /* search buffer */
- {
- register unsigned int i;
- register int j,k=-1;
- if (byte_cnt<findlen)
- return(ERROR);
- for (i=0,j=0;j>=0 && i<byte_cnt;i+=(j+findlen))
- {
- if (kase)
- j=isearch(&data_buf[i],(unsigned char *)findstr,byte_cnt-i,findlen);
- else
- j=search(&data_buf[i],(unsigned char *)findstr,byte_cnt-i,findlen);
- if (j > 0)
- {
- conout(' ');
- pn(j+i,Radix);
- conout(' ');
- k++;
- if (kbhit())
- return(ABORT);
- }
- }
- return(k);
- }
-
- if (Display)
- {
- /*conout(' ');*/
- conout((val==1)?'+':'-');
- }
- do /* search disk */
- {
- if (Display)
- {
- pln(ntimes,Radix);
- put((int)length(ntimes),8);
- }
- if ((io=movesector(val)) != DISK_OK)
- {
- if (Display)
- conout(8);
- printerror(Debug);
- if (io==DISK_NREADY && !getver("continue",CLR_ARG))
- {
- put(2,8);
- break;
- }
- if (Display)
- conout((val==1)?'+':'-');
- }
- if (++ntimes >= num_sectors)
- {
- if (Display)
- conout(8);
- if (!getver(" not found, continue",CLR_ARG))
- break;
- ntimes=0;
- }
- else if (kbhit()) /* check for abort */
- break;
- if (kase)
- findval=isearch(sec_buf,(unsigned char *)findstr,sec_size,findlen);
- else
- findval=search(sec_buf,(unsigned char *)findstr,sec_size,findlen);
- } while (findval == -1);
-
- if (Display)
- {
- conout(8);
- clreol();
- }
- return(findval);
- }
-
- /*
- Read the next sector, display, continue. Checks console for
- speed control and abort.
- pass: direction, forward or backward. value, number of sectors
-
- ver 1.1 9/91 added +1 to kbhit loop to correct '0' bug
- */
-
- void range(int val)
- {
- register int i;
- static int speed=4*50;
- int io;
- int c='4',b='4';
-
- for (;;)
- {
- if ((io=movesector(val)) != DISK_OK)
- {
- send('\n');
- printerror(Debug);
- if (io==DISK_NREADY) /* door open! */
- break;
- }
- dumpsector();
- for (i=0;i<speed;i++) /* loop in wait */
- if (kbhit())
- c=getch();
- if (isdigit(c)) /* reset speed, the same if c */
- {
- speed=((c-'0')*50+1); /* did not change */
- b=c;
- }
- else if (c==' ')
- {
- cconin();
- c=b;
- }
- else
- break;
- }
- }
-
- /***
- *dumpsector() - display sector buffer (front-end)
- *
- * 2.1 04-Jan-1994 added Translate if !Files for startup
- ****/
-
- void dumpsector()
- {
- int i=sectortocluster(log_sector);
- word sector = (word)log_sector;
-
- send('\n');
- header();
- if (Translate)
- if ( (Files && clusters[i]>0 && files[clusters[i]].dir)
- || (sector >= dir_sector && sector <= data_sector)
- || sectortocluster(log_sector) == dir_cluster
- )
- {
- dumpdir(sec_buf,sec_size);
- return;
- }
- if (!Ascii)
- {
- if (Partial)
- dump(sec_buf,0,sec_size,128,Radix);
- else
- dumpf(sec_buf,sec_size,Radix);
- }
- else
- view(sec_buf,0,sec_size,NOPAUSE,Radix);
- if (Partial || Ascii)
- send('\n');
- }
-
- void help(void)
- {
- int c;
-
- print(" Dir Boot Fat ?");
- c = (int)(char)conin();
- if (c == 'd')
- {
- print("\n\n\tDirectory Entry:\n");
- print("\t00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
- print("\t| filename | ext |at| reserved |\n");
- print("\t10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F\n");
- print("\t| reserved |time |date |start|file size |\n\n");
- print("\tnote: DRDOS uses the reserved area for deleted \n");
- print("\t file first char and password info. \n");
- }
- else if (c == 'b')
- print(" not yet");
- else if (c == 'f')
- print(" not yet");
- }
-